home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / MSJV7_2B.ARJ / SERVER.C < prev    next >
C/C++ Source or Header  |  1992-03-01  |  17KB  |  521 lines

  1. /*
  2.   OLE SERVER DEMO           
  3.   Server.c             
  4.                                                                      
  5.   This file contains server methods and various server-related support 
  6.   functions.
  7.                                                                      
  8.   (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved   
  9. */                                                                     
  10.  
  11.  
  12.  
  13. #define SERVERONLY
  14. #include "Windows.h"
  15. #include "Ole.h"
  16. #include "SrvrDemo.h"
  17.  
  18. /* 
  19.    Important Note:
  20.  
  21.    No method should ever dispatch a DDE message or allow a DDE message to
  22.    be dispatched.
  23.    Therefore, no method should ever enter a message dispatch loop.
  24.    Also, a method should not show a dialog or message box, because the 
  25.    processing of the dialog box messages will allow DDE messages to be
  26.    dispatched.
  27. */
  28.  
  29.  
  30. /* Abbrev
  31.  * ------
  32.  *
  33.  * Return a pointer to the filename part of a fully-qualified pathname.
  34.  *
  35.  * LPSTR lpsz - Fully qualified pathname
  36.  * 
  37.  * CUSTOMIZATION: May be useful, but not necessary.
  38.  *
  39.  */
  40. LPSTR Abbrev (LPSTR lpsz)
  41. {
  42.    LPSTR lpszTemp;
  43.    
  44.    lpszTemp = lpsz + lstrlen(lpsz) - 1;
  45.    while (lpszTemp > lpsz && lpszTemp[-1] != '\\')
  46.       lpszTemp--;
  47.    return lpszTemp;
  48. }
  49.  
  50.  
  51.  
  52. /* FreeVTbls
  53.  * ---------
  54.  *
  55.  * Free the instances of all the OLE methods created by InitVTbls.
  56.  *
  57.  * 
  58.  * CUSTOMIZATION: Your application might not use global variables for srvrvtbl,
  59.  *                docvtbl, and objvtbl.
  60.  */
  61. void FreeVTbls (void)
  62. {
  63.    FreeProcInstance (srvrvtbl.Create);
  64.    FreeProcInstance (srvrvtbl.CreateFromTemplate);
  65.    FreeProcInstance (srvrvtbl.Edit);
  66.    FreeProcInstance (srvrvtbl.Exit);
  67.    FreeProcInstance (srvrvtbl.Open);
  68.    FreeProcInstance (srvrvtbl.Release);
  69.  
  70.    FreeProcInstance (docvtbl.Close);
  71.    FreeProcInstance (docvtbl.GetObject);
  72.    FreeProcInstance (docvtbl.Release);
  73.    FreeProcInstance (docvtbl.Save);
  74.    FreeProcInstance (docvtbl.SetColorScheme);
  75.    FreeProcInstance (docvtbl.SetDocDimensions);
  76.    FreeProcInstance (docvtbl.SetHostNames);
  77.  
  78.    FreeProcInstance (objvtbl.DoVerb);
  79.    FreeProcInstance (objvtbl.EnumFormats);
  80.    FreeProcInstance (objvtbl.GetData);
  81.    FreeProcInstance ((FARPROC)objvtbl.QueryProtocol);
  82.    FreeProcInstance (objvtbl.Release);
  83.    FreeProcInstance (objvtbl.SetBounds);
  84.    FreeProcInstance (objvtbl.SetColorScheme);
  85.    FreeProcInstance (objvtbl.SetData);
  86.    FreeProcInstance (objvtbl.SetTargetDevice);
  87.    FreeProcInstance (objvtbl.Show);
  88. }
  89.  
  90.  
  91.  
  92. /* InitServer
  93.  * ----------
  94.  *
  95.  * Initialize the server by allocating memory for it, and calling
  96.  * the OleRegisterServer method.  Requires that the server method table
  97.  * has been properly initialized.
  98.  * 
  99.  * HWND hwnd      - Handle to the main window
  100.  * LPSTR lpszLine - The Windows command line
  101.  * 
  102.  * RETURNS: TRUE if the memory could be allocated, and the server
  103.  *          was properly registered.
  104.  *          FALSE otherwise
  105.  *
  106.  * CUSTOMIZATION: Your application might not use a global variable 
  107.  *                for srvrMain.
  108.  *
  109.  */
  110. BOOL InitServer (HWND hwnd, HANDLE hInst)
  111. {
  112.     srvrMain.olesrvr.lpvtbl = &srvrvtbl;
  113.  
  114.     if (OLE_OK != OleRegisterServer
  115.          (szClassName, (LPOLESERVER) &srvrMain, &srvrMain.lhsrvr, hInst, 
  116.           OLE_SERVER_MULTI))
  117.       return FALSE;
  118.     else
  119.       return TRUE;
  120. }
  121.  
  122.  
  123.  
  124. /* InitVTbls
  125.  * ---------
  126.  *
  127.  * Create procedure instances for all the OLE methods.
  128.  * 
  129.  * 
  130.  * CUSTOMIZATION: Your application might not use global variables for srvrvtbl,
  131.  *                docvtbl, and objvtbl.
  132.  */
  133. void InitVTbls (void)
  134. {
  135.    typedef LPVOID (FAR PASCAL *LPVOIDPROC) (LPOLEOBJECT, LPSTR);
  136.  
  137.    // Server method table
  138.    srvrvtbl.Create          = MakeProcInstance (SrvrCreate,          hInst);
  139.    srvrvtbl.CreateFromTemplate
  140.                             = MakeProcInstance (SrvrCreateFromTemplate,hInst);
  141.    srvrvtbl.Edit            = MakeProcInstance (SrvrEdit,            hInst);
  142.    srvrvtbl.Execute         = MakeProcInstance (SrvrExecute,         hInst);
  143.    srvrvtbl.Exit            = MakeProcInstance (SrvrExit,            hInst);
  144.    srvrvtbl.Open            = MakeProcInstance (SrvrOpen,            hInst);
  145.    srvrvtbl.Release         = MakeProcInstance (SrvrRelease,         hInst);
  146.  
  147.    // Document method table
  148.    docvtbl.Close            = MakeProcInstance (DocClose,            hInst);
  149.    docvtbl.GetObject        = MakeProcInstance (DocGetObject,        hInst);
  150.    docvtbl.Execute          = MakeProcInstance (DocExecute,          hInst);
  151.    docvtbl.Release          = MakeProcInstance (DocRelease,          hInst);
  152.    docvtbl.Save             = MakeProcInstance (DocSave,             hInst);
  153.    docvtbl.SetColorScheme   = MakeProcInstance (DocSetColorScheme,   hInst);
  154.    docvtbl.SetDocDimensions = MakeProcInstance (DocSetDocDimensions, hInst);
  155.    docvtbl.SetHostNames     = MakeProcInstance (DocSetHostNames,     hInst);
  156.  
  157.    // Object method table
  158.    objvtbl.DoVerb           = MakeProcInstance (ObjDoVerb,           hInst);
  159.    objvtbl.EnumFormats      = MakeProcInstance (ObjEnumFormats,      hInst);
  160.    objvtbl.GetData          = MakeProcInstance (ObjGetData,          hInst);
  161.    objvtbl.QueryProtocol    = (LPVOIDPROC) MakeProcInstance 
  162.                                  ((FARPROC)ObjQueryProtocol,hInst);
  163.    objvtbl.Release          = MakeProcInstance (ObjRelease,          hInst);
  164.    objvtbl.SetBounds        = MakeProcInstance (ObjSetBounds,        hInst);
  165.    objvtbl.SetColorScheme   = MakeProcInstance (ObjSetColorScheme,   hInst);
  166.    objvtbl.SetData          = MakeProcInstance (ObjSetData,          hInst);
  167.    objvtbl.SetTargetDevice  = MakeProcInstance (ObjSetTargetDevice,  hInst);
  168.    objvtbl.Show             = MakeProcInstance (ObjShow,             hInst);
  169. }
  170.  
  171.  
  172.  
  173. /* SetTitle 
  174.  * --------
  175.  *
  176.  * Sets the main window's title bar. The format of the title bar is as follows
  177.  *   
  178.  * If embedded
  179.  *        <Server App name> - <object type> in <client doc name>
  180.  *   
  181.  *      Example:  "Server Demo - SrvrDemo Shape in OLECLI.DOC"
  182.  *                where OLECLI.DOC is a Winword document
  183.  *   
  184.  * otherwise
  185.  *        <Server App name> - <server document name>     
  186.  *   
  187.  *      Example:  "Server Demo - OLESVR.SD" 
  188.  *                where OLESVR.SD is a Server demo document
  189.  *
  190.  * LPSTR lpszDoc    - document name
  191.  * BOOL  fEmbedded  - If TRUE embedded document, else normal document      
  192.  * 
  193.  * RETURNS: OLE_OK
  194.  *
  195.  * 
  196.  * CUSTOMIZATION: Your application may store the document's name somewhere
  197.  *                other than docMain.aName.  Other than that, you may
  198.  *                find this a useful utility function as is.
  199.  *
  200.  */
  201. void SetTitle (LPSTR lpszDoc, BOOL fEmbedded)
  202. {
  203.    char szBuf[cchFilenameMax];
  204.  
  205.    if (lpszDoc && lpszDoc[0])
  206.    {
  207.       // Change document name.
  208.       if (docMain.aName)
  209.          GlobalDeleteAtom (docMain.aName);
  210.       docMain.aName = GlobalAddAtom (lpszDoc);
  211.    }
  212.  
  213.    if (fEmbedded)
  214.    {
  215.      // 
  216.       if (lpszDoc && lpszDoc[0]) 
  217.       {
  218.          wsprintf (szBuf, "%s - SrvrDemo Shape in %s", (LPSTR) szAppName, 
  219.              Abbrev (lpszDoc));
  220.       }
  221.       else
  222.       {
  223.          // Use name from docMain
  224.          char szDoc [cchFilenameMax];
  225.      
  226.          GlobalGetAtomName (docMain.aName, szDoc, cchFilenameMax);
  227.          wsprintf (szBuf, "%s - SrvrDemo Shape in %s", (LPSTR) szAppName, 
  228.              Abbrev (szDoc));
  229.       }
  230.       SetWindowText (hwndMain, (LPSTR)szBuf);
  231.    } 
  232.    else if (lpszDoc && lpszDoc[0])
  233.    {
  234.       wsprintf (szBuf, "%s - %s", (LPSTR) szAppName, Abbrev(lpszDoc));
  235.       SetWindowText (hwndMain, szBuf);
  236.    }
  237. }
  238.  
  239.  
  240.  
  241.  
  242. /* SrvrCreate                SERVER "Create" METHOD
  243.  * ----------
  244.  *
  245.  * Create a document, allocate and initialize the OLESERVERDOC structure,
  246.  * and associate the library's handle with it.
  247.  * In this demo server, we also create an object for the user to edit.
  248.  * 
  249.  * LPOLESERVER lpolesrvr          - The server structure registered by
  250.  *                                  the application
  251.  * LHSERVERDOC lhdoc              - The library's handle
  252.  * LPSTR lpszClassName            - The class of document to create
  253.  * LPSTR lpszDoc                  - The name of the document
  254.  * LPOLESERVERDOC FAR *lplpoledoc - Indicates the server doc structure to be
  255.  *                                  created
  256.  * 
  257.  * RETURNS:        OLE_OK if the named document was created.
  258.  *                 OLE_ERROR_NEW if the document could not be created.
  259.  * 
  260.  * CUSTOMIZATION: Your application might not call CreateNewObj.
  261.  *
  262.  */
  263. OLESTATUS FAR PASCAL SrvrCreate
  264.    (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpszClassName, 
  265.     LPSTR lpszDoc, LPOLESERVERDOC FAR *lplpoledoc)
  266. {
  267.     if (!CreateNewDoc (lhdoc, lpszDoc, doctypeEmbedded)) 
  268.         return OLE_ERROR_NEW;
  269.  
  270.     // Although the document has not actually been changed, the client has not
  271.     // received any data from the server yet, so the client will need to be
  272.     // updated.  Therefore, CreateNewObj sets fDocChanged to TRUE.
  273.     CreateNewObj (TRUE);
  274.     *lplpoledoc = (LPOLESERVERDOC) &docMain;
  275.     EmbeddingModeOn();
  276.     return OLE_OK;
  277. }
  278.  
  279.  
  280.  
  281. /* SrvrCreateFromTemplate        SERVER "CreateFromTemplate" METHOD
  282.  * ----------------------
  283.  *
  284.  * Create a document, allocate and initialize the OLESERVERDOC structure, 
  285.  * initializing the document with the contents named in the template name, 
  286.  * and associate the library's handle with the document structure.
  287.  * 
  288.  * LPOLESERVER lpolesrvr        - The server structure registered by
  289.  *                                the application
  290.  * LHSERVERDOC lhdoc            - The library's handle
  291.  * LPSTR lpszClassName          - The class of document to create
  292.  * LPSTR lpszDoc                - The name of the document
  293.  * LPSTR lpszTemplate           - The name of the template
  294.  * LPOLESERVERDOC FAR *lplpoledoc - Indicates the server doc structure 
  295.  *                                  to be created
  296.  * 
  297.  * RETURNS:        OLE_OK if the named document was created.
  298.  *                 OLE_ERROR_TEMPLATE if the document could not be created.
  299.  *
  300.  * CUSTOMIZATION: None
  301.  *
  302.  */
  303. OLESTATUS FAR PASCAL SrvrCreateFromTemplate
  304.    (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpszClassName, 
  305.     LPSTR lpszDoc, LPSTR lpszTemplate, LPOLESERVERDOC FAR *lplpoledoc)
  306. {
  307.     if (!CreateDocFromFile(lpszTemplate, lhdoc, doctypeEmbedded)) 
  308.         return OLE_ERROR_TEMPLATE;
  309.  
  310.     *lplpoledoc = (LPOLESERVERDOC) &docMain;
  311.  
  312.     // Although the document has not actually been changed, the client has not
  313.     // received any data from the server yet, so the client will need to be
  314.     // updated.
  315.     fDocChanged = TRUE;
  316.     EmbeddingModeOn();
  317.     return OLE_OK;
  318. }
  319.  
  320.  
  321.  
  322. /* SrvrEdit                SERVER "Edit" METHOD
  323.  * --------
  324.  *
  325.  * A request by the libraries to create a document, allocate and
  326.  * initialize the OLESERVERDOC structure, and associate the
  327.  * library's handle with the document structure.
  328.  * We create an object which will be modified by the SetData method
  329.  * before the user has a chance to touch it.
  330.  * 
  331.  * LPOLESERVER lpolesrvr          - The server structure registered by
  332.  *                                  the application
  333.  * LHSERVERDOC lhdoc              - The library's handle
  334.  * LPSTR lpszClassName            - The class of document to create
  335.  * LPSTR lpszDoc                  - The name of the document
  336.  * LPOLESERVERDOC FAR *lplpoledoc - Indicates the server doc structure to be
  337.  *                                  created
  338.  * 
  339.  * RETURNS:        OLE_OK if the named document was created.
  340.  *                 OLE_ERROR_EDIT if the document could not be created.
  341.  * 
  342.  * CUSTOMIZATION: None
  343.  *
  344.  */
  345. OLESTATUS FAR PASCAL SrvrEdit 
  346.    (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpszClassName, 
  347.     LPSTR lpszDoc, LPOLESERVERDOC FAR *lplpoledoc)
  348. {
  349.     if (!CreateNewDoc (lhdoc, lpszDoc, doctypeEmbedded))
  350.         return OLE_ERROR_EDIT;
  351.  
  352.     // The client is creating an embedded object for the server to edit,
  353.     // so initially the client and server are in sync.
  354.     fDocChanged = FALSE;
  355.     *lplpoledoc = (LPOLESERVERDOC) &docMain;
  356.     EmbeddingModeOn();
  357.     return OLE_OK;
  358.  
  359. }
  360.  
  361.  
  362. /* SrvrExecute                SERVER "Execute" METHOD
  363.  * --------
  364.  *
  365.  * This application does not support the execution of DDE execution commands.
  366.  * 
  367.  * LPOLESERVER lpolesrvr - The server structure registered by
  368.  *                         the application
  369.  * HANDLE hCommands      - DDE execute commands
  370.  * 
  371.  * RETURNS: OLE_ERROR_COMMAND
  372.  *
  373.  * CUSTOMIZATION: Re-implement if your application supports the execution of
  374.  *                DDE commands.
  375.  *
  376.  */
  377. OLESTATUS FAR PASCAL SrvrExecute (LPOLESERVER lpolesrvr, HANDLE hCommands)
  378. {
  379.    return OLE_ERROR_COMMAND;
  380. }
  381.  
  382.  
  383.  
  384. /* SrvrExit                SERVER "Exit" METHOD
  385.  * --------
  386.  *
  387.  * This method is called the library to instruct the server to exit.
  388.  * 
  389.  * LPOLESERVER lpolesrvr - The server structure registered by
  390.  *                         the application
  391.  * 
  392.  * RETURNS: OLE_OK
  393.  * 
  394.  * CUSTOMIZATION: None
  395.  *
  396.  */
  397. OLESTATUS FAR PASCAL SrvrExit (LPOLESERVER lpolesrvr)
  398. {
  399.    if (srvrMain.lhsrvr)
  400.    // If we haven't already tried to revoke the server.
  401.    {
  402.       StartRevokingServer();
  403.    }
  404.    return OLE_OK;
  405. }
  406.  
  407.  
  408.  
  409. /* SrvrOpen                SERVER "Open" METHOD
  410.  * --------
  411.  *
  412.  * Open the named document, allocate and initialize the OLESERVERDOC 
  413.  * structure, and associate the library's handle with it.
  414.  * 
  415.  * LPOLESERVER lpolesrvr          - The server structure registered by
  416.  *                                  the application
  417.  * LHSERVERDOC lhdoc              - The library's handle
  418.  * LPSTR lpszDoc                  - The name of the document
  419.  * LPOLESERVERDOC FAR *lplpoledoc - Indicates server doc structure to be
  420.  *                                  created
  421.  * 
  422.  * RETURNS:        OLE_OK if the named document was opened.
  423.  *                 OLE_ERROR_OPEN if document could not be opened correctly.
  424.  * 
  425.  * CUSTOMIZATION: None
  426.  *
  427.  */
  428. OLESTATUS FAR PASCAL SrvrOpen (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc,
  429.                                LPSTR lpszDoc, LPOLESERVERDOC FAR *lplpoledoc)
  430. {
  431.     if (!CreateDocFromFile (lpszDoc, lhdoc, doctypeFromFile))
  432.         return OLE_ERROR_OPEN;
  433.  
  434.     *lplpoledoc = (LPOLESERVERDOC) &docMain;
  435.     return OLE_OK;
  436. }
  437.  
  438.  
  439.  
  440. /* SrvrRelease                SERVER "Release" METHOD
  441.  * -----------
  442.  *
  443.  * This library calls the SrvrRelease method when it is safe to quit the
  444.  * application.  Note that the server application is not required to quit.
  445.  * 
  446.  * srvrMain.lhsrvr != NULL indicates that SrvrRelease has been called
  447.  * because the client is no longer connected, not because the server called
  448.  * OleRevokeServer.
  449.  * Therefore, only start the revoking process if the document is of type
  450.  * doctypeEmbedded or if the server was opened for an invisible update.
  451.  * 
  452.  * srvrmain.lhsrvr == NULL indicates that OleRevokeServer has already 
  453.  * been called (by the server application), and srvrMain is a lame duck.
  454.  * It is safe to quit now because SrvrRelease has just been called.
  455.  *
  456.  * Note that this method may be called twice: when OleRevokeServer is 
  457.  * called in StartRevokingServer, SrvrRelease is called again.  
  458.  * Therefore we need to be reentrant.
  459.  * 
  460.  * LPOLESERVER lpolesrvr - The server structure to release
  461.  * 
  462.  * RETURNS: OLE_OK
  463.  * 
  464.  * CUSTOMIZATION: None
  465.  *
  466.  */
  467. OLESTATUS FAR PASCAL SrvrRelease (LPOLESERVER lpolesrvr)
  468. {
  469.    if (srvrMain.lhsrvr)
  470.    {
  471.       if (fRevokeSrvrOnSrvrRelease 
  472.           && (docMain.doctype == doctypeEmbedded 
  473.               || !IsWindowVisible (hwndMain)))
  474.          StartRevokingServer();
  475.    }
  476.    else      
  477.    {
  478.       fWaitingForSrvrRelease = FALSE;
  479.       // Here you should free any memory that had been allocated for the server.
  480.       PostQuitMessage (0);
  481.    }
  482.    return OLE_OK;
  483. }
  484.  
  485.  
  486.  
  487. /* StartRevokingServer
  488.  * -------------------
  489.  *
  490.  * Hide the window, and start to revoke the server.  
  491.  * Revoking the server will let the library close any registered documents.
  492.  * OleRevokeServer may return OLE_WAIT_FOR_RELEASE.
  493.  * Calling StartRevokingServer starts a chain of events that will eventually
  494.  * lead to the application being terminated.
  495.  *
  496.  * RETURNS: The return value from OleRevokeServer
  497.  *
  498.  * CUSTOMIZATION: None
  499.  *
  500.  */
  501. OLESTATUS StartRevokingServer (void)
  502. {
  503.    OLESTATUS olestatus;
  504.  
  505.    if (srvrMain.lhsrvr)
  506.    {
  507.       LHSERVER lhserver;
  508.       // Hide the window so user can do nothing while we are waiting. 
  509.       ShowWindow (hwndMain, SW_HIDE);
  510.       lhserver = srvrMain.lhsrvr;
  511.       // Set lhsrvr to NULL to indicate that srvrMain is a lame duck and that
  512.       // if SrvrRelease is called, then it is ok to quit the application.
  513.       srvrMain.lhsrvr = NULL;
  514.       olestatus = OleRevokeServer (lhserver);
  515.    }
  516.    else
  517.       // The programmer should ensure that this never happens.
  518.       ErrorBox ("Fatal Error: StartRevokingServer called on NULL server.");
  519.    return olestatus;
  520. }
  521.